/*
* Copyright 2017 Yonyou Auto Information Technology（Shanghai） Co., Ltd. All Rights Reserved.
*
* This software is published under the terms of the YONYOU Software
* License version 1.0, a copy of which has been included with this
* distribution in the LICENSE.txt file.
*
* @Project Name : marketing-common
*
* @File name : CopyOfStringUtil.java
*
* @Author : Administrator
*
* @Date : 2017年8月7日
*
----------------------------------------------------------------------------------
*     Date       Who       Version     Comments
* 1. 2017年8月7日    Administrator    1.0
*
*
*
*
----------------------------------------------------------------------------------
*/

package org.marketing.common.util;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

/**
 * @author Administrator TODO description
 * @date 2017年8月7日
 */

public class CopyOfStringUtil {
	private static Logger logger = Logger.getLogger(CopyOfStringUtil.class);
    /**
     * 定义分割常量 #用于list中每个元素间的分割 |用于map中每一个kv对间的分割 =用于map中key与value间的分割
     */
    private static final String SEP1 = ",";
    private static final String SEP2 = "|";
    private static final String SEP3 = "=";

    /**
     * List转换String
     * 
     * @param list :需要转换的List
     * @return String转换后的字符串
     */
    public static String ListToString(List<?> list) {
        StringBuffer sb = new StringBuffer();
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                if (list.get(i) == null || list.get(i) == "") {
                    continue;
                }
                // 如果值是list类型则调用自己
                if (list.get(i) instanceof List) {
                    sb.append(ListToString((List<?>) list.get(i)));
                    sb.append(SEP1);
                } else if (list.get(i) instanceof Map) {
                    sb.append(MapToString((Map<?, ?>) list.get(i)));
                    sb.append(SEP1);
                } else {
                    sb.append(list.get(i));
                    sb.append(SEP1);
                }
            }
        }
        return "L" + sb.toString();
    }

    /**
     * Map转换String
     * 
     * @param map :需要转换的Map
     * @return String转换后的字符串
     */
    public static String MapToString(Map<?, ?> map) {
        StringBuffer sb = new StringBuffer();
        // 遍历map
        for (Object obj : map.keySet()) {
            if (obj == null) {
                continue;
            }
            Object key = obj;
            Object value = map.get(key);
            if (value instanceof List<?>) {
                sb.append(key.toString() + SEP1 + ListToString((List<?>) value));
                sb.append(SEP2);
            } else if (value instanceof Map<?, ?>) {
                sb.append(key.toString() + SEP1 + MapToString((Map<?, ?>) value));
                sb.append(SEP2);
            } else {
                sb.append(key.toString() + SEP3 + value.toString());
                sb.append(SEP2);
            }
        }
        return "M" + sb.toString();
    }

    /**
     * String转换Map
     * 
     * @param mapText :需要转换的字符串
     * @return Map<?,?>
     */
    public static Map<String, Object> StringToMap(String mapText) {

        if (mapText == null || mapText.equals("")) {
            return null;
        }
        mapText = mapText.substring(0);

        Map<String, Object> map = new HashMap<String, Object>();
        String[] text = mapText.split("\\" + SEP1); // 转换为数组
        for (String str : text) {
            String[] keyText = str.split(SEP3); // 转换key与value的数组
            if (keyText.length < 1) {
                continue;
            }
            String key = keyText[0]; // key
            String value = keyText[1]; // value
            if (value.charAt(0) == 'M') {
                Map<?, ?> map1 = StringToMap(value);
                map.put(key, map1);
            } else if (value.charAt(0) == 'L') {
                List<?> list = StringToList(value);
                map.put(key, list);
            } else {
                map.put(key, value);
            }
        }
        return map;
    }

    /**
     * String转换List
     * 
     * @param listText :需要转换的文本
     * @return List<?>
     */
    public static List<Object> StringToList(String listText) {
        if (listText == null || listText.equals("")) {
            return null;
        }
        listText = listText.substring(1);

        List<Object> list = new ArrayList<Object>();
        String[] text = listText.split("\\" + SEP1);
        String listStr = "";
        boolean flag = false;
        for (String str : text) {
            if (!str.equals("")) {
                if (str.charAt(0) == 'M') {
                    Map<?, ?> map = StringToMap(str);
                    list.add(map);
                } else if (str.charAt(0) == 'L' || flag) {
                    flag = true;
                    listStr += str + SEP1;
                } else {
                    list.add(str);
                }
            }
            if (str.equals("")) {
                flag = false;
                List<?> lists = StringToList(listStr);
                list.add(lists);
            }
        }
        return list;
    }
    /**
     * @param source :源对象
     * @param dest :目标对象
     */
    public static void Copy(Object source, Object dest) {  
        
        try{  
        	//获取属性  
            BeanInfo sourceBean = Introspector.getBeanInfo(source.getClass(), java.lang.Object.class);  
            PropertyDescriptor[] sourceProperty = sourceBean.getPropertyDescriptors();  
              
            BeanInfo destBean = Introspector.getBeanInfo(dest.getClass(), java.lang.Object.class);  
            PropertyDescriptor[] destProperty = destBean.getPropertyDescriptors();  
            for(int i=0;i<sourceProperty.length;i++){  
                  
                for(int j=0;j<destProperty.length;j++){  
                      
                    if(sourceProperty[i].getName().equals(destProperty[j].getName())){  
                        //调用source的getter方法和dest的setter方法  
                        destProperty[j].getWriteMethod().invoke(dest, sourceProperty[i].getReadMethod().invoke(source));  
                        break;                    
                    }  
                }  
            }  
        }catch(Exception e){  
        	logger.error("属性复制失败:"+e.getMessage(), e);
        }  
    }
    public static String generateSign(Map<String, Object> parm) {
        String _sign = "";
        if (null != parm) {
            Collection<String> keyset = parm.keySet();
            List<String> list = new ArrayList<String>(keyset);
            Collections.sort(list);
            for (int i = 0; i < list.size(); i++) {
                _sign += list.get(i) + "=" + parm.get(list.get(i));
            }
            _sign = (bytesToMD5(_sign.getBytes()) + "201707314421445a73b28be68be3861f199c5cf3");
            _sign = bytesToMD5(_sign.getBytes());
        }
        return _sign;
    }

    // 把字节数组转换成md5
    public static String bytesToMD5(byte[] input) {
        String md5str = null;
        try {
            // 创建一个提供信息摘要算法的对象，初始化为md5算法对象
            MessageDigest md = MessageDigest.getInstance("MD5");
            // 计算后获得字节数组
            byte[] buff = md.digest(input);
            // 把数组每一字节换成16进制连成md5字符串
            md5str = bytesToHex(buff);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return md5str;
    }
    
    public static String bytesToHex(byte[] bytes){
        StringBuffer md5str = new StringBuffer();
        //把数组每一字节换成16进制连成md5字符串
        int digital;
        for(int i =0;i<bytes.length;i++){
            digital = bytes[i];
            if(digital<0){
                digital += 256;
            }
            if(digital<16){
                md5str.append("0");
            }
            md5str.append(Integer.toHexString(digital));
        }
        return md5str.toString();
    }
}
